package com.yuxin.common.util;

import magick.ImageInfo;
import magick.MagickApiException;
import magick.MagickException;
import magick.MagickImage;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.http.HttpServletRequest;
import java.awt.*;
import java.io.File;
import java.util.*;
import java.util.List;

/**
 * @author zehui.zeng
 * @date 13-4-19 下午4:36
 */
public class FileUploadUtil {
    private static Log logger = LogFactory.getLog(FileUploadUtil.class);
    public static final String COMPRESS_FIX_SIZE = "1";// 固定大小
    public static final String COMPRESS_FIX_AND_SMALL = "4";// 固定大小,并生成缩略图
    public static final String COMPRESS_FIX_WIDTH = "2";// 固定宽度
    public static final String COMPRESS_SMALL_IMAGE = "3";// 生成缩略图，并压缩原图
    public static final String MAX_WIDTH = "800";// 最大图片宽度
    public static final int IMG_QUALITY = 50;//图片压缩质量

    /***
     * 文件上传
     * @param request
     * @return
     * @throws Exception
     */
    public static Map upload(HttpServletRequest request) throws Exception {
        Map user = (Map)request.getSession().getAttribute("user");
        String userName = "ccbcc_trader";
        if(user != null){
        	userName = StringUtils.getText(user.get("USERNAME"));
        }
        List<Map<String,String>> fileList = new ArrayList<Map<String, String>>();
        Map result = new HashMap();
        String rootPath = request.getSession().getServletContext().getRealPath("/");
        String filePath = "/file/"+userName+"/"+DateUtil.fomatDate(new Date(),"yyyyMMdd");
        File directory = new File(rootPath+filePath);
        if(!directory.isDirectory()){
            directory.mkdirs();
        }
        FileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 设置允许用户上传文件大小,单位:字节，这里设为2m
        //upload.setSizeMax(2 * 1024 * 1024);
        // 设置最多只允许在内存中存储的数据,单位:字节
        //factory.setSizeThreshold(4096);
        List<FileItem> items = upload.parseRequest(request);
        Map requestParameterMap = new HashMap();
        Iterator<FileItem> itr = items.iterator();
        String fileName = "";
        Map fileMap = null;
        while (itr.hasNext()) {
            FileItem item = (FileItem) itr.next();
            //检查当前项目是普通表单项目还是上传文件。
            if (!item.isFormField()) {//如果是普通表单项目，显示表单内容。
                logger.info("正在保存文件："+item.getFieldName());
                if(item.getSize() > 0){
                    fileMap = new HashMap();
                    fileName =filePath+"/"+UUIDUtil.getUUID()+"."+StringUtils.getFilenameExtension(item.getName());
                    fileMap.put("filed",item.getFieldName());
                    fileMap.put("size",item.getSize());
                    fileMap.put("path",fileName);
                    fileMap.put("ext",StringUtils.getFilenameExtension(item.getName()));
                    fileMap.put("origPath",rootPath+fileName.replaceFirst("/",""));// 图片路径
                    fileList.add(fileMap);
                    item.write(new File(rootPath+fileName));
                }
            }else{
                requestParameterMap.put(item.getFieldName(),item.getString("UTF-8"));
            }
        }
        result.put("files",fileList);
        result.put("formData",requestParameterMap);
        return result;
    }


    /**
     * 图片上传
     * @param request
     * @param uploadSet
     * @return
     * @throws Exception
     */
    public static Map upload(HttpServletRequest request,Map<String,String> uploadSet) throws Exception {
        Map fileUploadMap = upload(request);
        List<Map> fileList = (List<Map>)fileUploadMap.get("files");
        if(CollectionUtils.isEmpty(fileList)){
            return fileUploadMap;
        }
        for(Map fileMap : fileList){
            String origPath = StringUtils.getText(fileMap.get("origPath"));
            Integer size = null;
            if("gif;png;jpg;".indexOf(fileMap.get("ext").toString().toLowerCase()) == -1){continue;}
            switch (uploadSet.get("type").charAt(0)){
                case '1':// 固定图片大小
                    size = resizeImageFixWH(origPath,origPath,Integer.valueOf(uploadSet.get("width")),Integer.valueOf(uploadSet.get("height")));
                    break;
                case '2':// 固定宽度/高度
                    // 判断是否指定图片压缩大小
                    if(uploadSet.get(fileMap.get("filed"))!=null){
                        String[] sizes = (uploadSet.get(fileMap.get("filed"))+"").split("\\*");
                        if(sizes.length == 2){
                        	if(Integer.valueOf(sizes[0]) == 0){
                                size = resizeImageFixH(origPath,origPath,Integer.valueOf(sizes[1]));
                        	}else{
                        		size = resizeImageFixWH(origPath,origPath,Integer.valueOf(sizes[0]),Integer.valueOf(sizes[1]));
                        	}
                        }else{
                            size = resizeImageFixW(origPath,origPath,Integer.valueOf(sizes[0]));
                        }
                    }else{
                        size = resizeImageFixW(origPath,origPath,Integer.valueOf(MAX_WIDTH));
                    }
                    break;
                case '3':
                    size = resizeImageFixW(origPath,origPath,Integer.valueOf(MAX_WIDTH));
                    Integer smallSize = resizeImageFixWH(origPath,origPath+".s.jpg",Integer.valueOf(uploadSet.get("width")),Integer.valueOf(uploadSet.get("height")));
                    if(size != null && smallSize != null){
                        size += smallSize;
                    }else if(size == null && smallSize != null){
                        size = Integer.valueOf(fileMap.get("size")+"")+smallSize;
                    }
                    fileMap.put("samllFilePath",origPath+".s.jpg");
                    break;
                case '4'://固定大小,并生成缩略图
                    String[] fixSizes = (uploadSet.get("fix")).split("\\*");
                    size = resizeImageFixWH(origPath,origPath,Integer.valueOf(fixSizes[0]),Integer.valueOf(fixSizes[1]));
                    String[] smallSizes = (uploadSet.get("small")).split("\\*");
                    Integer sSize = resizeImageFixWH(origPath,origPath+".s.jpg",Integer.valueOf(smallSizes[0]),Integer.valueOf(smallSizes[1]));
                    if(size != null && sSize != null){
                        size += sSize;
                    }else if(size == null && sSize != null){
                        size = Integer.valueOf(fileMap.get("size")+"")+sSize;
                    }
                    fileMap.put("samllFilePath",origPath+".s.jpg");
                	break;
            }
            if(size != null){
                fileMap.put("size",size);
            }
        }
        return fileUploadMap;
    }

    /**
     * 固定图片大小
     * @param picFrom
     * @param picTo
     * @param w
     * @param h
     */
    public static Integer resizeImageFixWH(String picFrom, String picTo,int w,int h) throws Exception {
        System.setProperty("jmagick.systemclassloader", "no");
        Integer fileSize = null;
        MagickImage image = new MagickImage(new ImageInfo(picFrom));
        try {
            logger.debug("生成固定大小图片：" + picFrom + "  " + picTo);
            ImageInfo info = new ImageInfo(picFrom);
            Dimension imageDim = image.getDimension();
            // 若原始图片尺寸小于，压缩后的图片尺寸，则不处理
            /*if(imageDim.width < w || imageDim.height < h){
                return fileSize;
            }*/
            int width = imageDim.width > w ? w:imageDim.width ;
            int height = imageDim.height > h ? h:imageDim.height;
            logger.info("width:" + width + " h:" + height);
            MagickImage scaled = image.scaleImage(width, height);// 小图片文件的大小.
            scaled.setFileName(picTo);
            info.setQuality(IMG_QUALITY);// 图片压缩质量
            scaled.writeImage(info);
            fileSize = scaled.sizeBlob();
        } catch (MagickApiException ex) {
            logger.error("MagickException: " + ex + ": " + ex.getReason() + ", " + ex.getDescription());
            throw new Exception(ex);
            // ex.printStackTrace();
        } catch (MagickException ex) {
            logger.error("MagickException: " ,ex);
            throw new Exception(ex);
        } catch (Exception ex) {
            logger.error("Image resize error: " + ex);
            ex.printStackTrace();
            throw new Exception(ex);
        }finally {
            image.destroyImages();
        }
        return fileSize;
    }

    /**
     * 固定图片宽度
     * @param picFrom
     * @param picTo
     * @param w
     */
    public static Integer resizeImageFixW(String picFrom, String picTo,int w) throws Exception {
        System.setProperty("jmagick.systemclassloader", "no");
        Integer fileSize = null;
        MagickImage image = new MagickImage(new ImageInfo(picFrom));
        try {
            logger.debug("生成固定宽度图片：" + picFrom + "  " + picTo);
            ImageInfo info = new ImageInfo(picFrom);
            Dimension imageDim = image.getDimension();
            // 若原始图片尺寸小于，压缩后的图片尺寸，则不处理
            /* if(imageDim.width < w){
                return fileSize;
            }*/
            int width = imageDim.width >w ? w:imageDim.width ;
            int height = width * imageDim.height/imageDim.width;
            logger.info("w:" + width + " h:" + height);
            MagickImage scaled = image.scaleImage(width, height);// 小图片文件的大小.
            scaled.setFileName(picTo);
            info.setQuality(IMG_QUALITY);// 图片压缩质量
            scaled.writeImage(info);
            fileSize = scaled.sizeBlob();
        } catch (MagickApiException ex) {
            logger.error("MagickException: " + ex + ": " + ex.getReason() + ", " + ex.getDescription());
            throw new Exception(ex);
        } catch (MagickException ex) {
            logger.error("MagickException: " ,ex);
            throw new Exception(ex);
        } catch (Exception ex) {
            logger.error("Image resize error: " + ex);
            ex.printStackTrace();
            throw new Exception(ex);
        }finally {
            image.destroyImages();
        }
        return fileSize;
    }

    /**
     * 固定图片高度
     * @param picFrom
     * @param picTo
     * @param h
     */
    public static Integer resizeImageFixH(String picFrom, String picTo,int h) throws Exception {
        System.setProperty("jmagick.systemclassloader", "no");
        Integer fileSize = null;
        MagickImage image = new MagickImage(new ImageInfo(picFrom));
        try {
            logger.debug("生成固定高度图片：" + picFrom + "  " + picTo);
            ImageInfo info = new ImageInfo(picFrom);
            Dimension imageDim = image.getDimension();
            // 若原始图片尺寸小于，压缩后的图片尺寸，则不处理
            /* if(imageDim.width < w){
                return fileSize;
            }*/
            int height = imageDim.height >h ? h:imageDim.height ;
            int width = height * imageDim.width/imageDim.height;
            logger.info("w:" + width + " h:" + height);
            MagickImage scaled = image.scaleImage(width, height);// 小图片文件的大小.
            scaled.setFileName(picTo);
            info.setQuality(IMG_QUALITY);// 图片压缩质量
            scaled.writeImage(info);
            fileSize = scaled.sizeBlob();
        } catch (MagickApiException ex) {
            logger.error("MagickException: " + ex + ": " + ex.getReason() + ", " + ex.getDescription());
            throw new Exception(ex);
        } catch (MagickException ex) {
            logger.error("MagickException: " ,ex);
            throw new Exception(ex);
        } catch (Exception ex) {
            logger.error("Image resize error: " + ex);
            ex.printStackTrace();
            throw new Exception(ex);
        }finally {
            image.destroyImages();
        }
        return fileSize;
    }
    /*** 图片压缩 ***/
    public static Integer resizeImage(String picFrom, String picTo,int w,int h) throws Exception {
        System.setProperty("jmagick.systemclassloader", "no");
        Integer fileSize = null;
        MagickImage image = new MagickImage(new ImageInfo(picFrom));
        try {
            logger.debug("生成缩略图：" + picFrom + "  " + picTo);
            ImageInfo info = new ImageInfo(picFrom);
            Dimension imageDim = image.getDimension();
            // 若原始图片尺寸小于，压缩后的图片尺寸，则不处理
            if(imageDim.width < w || imageDim.height < h){
                return fileSize;
            }
            int width = imageDim.width >w ? w:imageDim.width ;
            int height = width * imageDim.height/imageDim.width;
            height = height>h ? h : height;
            logger.info("w:" + width + " h:" + height);
            MagickImage scaled = image.scaleImage(width, height);// 小图片文件的大小.
            //MagickImage scaled = image.scaleImage(imageDim.width, imageDim.height);
            scaled.setFileName(picTo);
            info.setQuality(IMG_QUALITY);// 图片压缩质量
            scaled.writeImage(info);
            fileSize = scaled.sizeBlob();
        } catch (MagickApiException ex) {
            logger.error("MagickException: " + ex + ": " + ex.getReason() + ", " + ex.getDescription());
            throw new Exception(ex);
        } catch (MagickException ex) {
            logger.error("MagickException: " ,ex);
            throw new Exception(ex);
        } catch (Exception ex) {
            logger.error("Image resize error: " + ex);
            ex.printStackTrace();
            throw new Exception(ex);
        }finally {
            image.destroyImages();
        }
        return fileSize;
    }

    /*** 文件删除 ***/
    public static boolean deleteFile(HttpServletRequest request,String path){
    	if(!StringUtils.hasText(path)){
    		return false;
    	}
        String rootPath = request.getSession().getServletContext().getRealPath("/");
        File file = new File(rootPath+path);
        File sFile = new File(rootPath+path+".s.jpg");
        if(file.exists()){
        	file.delete();
        }
        if(sFile.exists()){
        	sFile.delete();
        }
    	return true;
    }
}
